package CRRestClient;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.junit.Test;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.support.RestGatewaySupport;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.ArrayList;
import java.util.List;

public class CRClient extends RestGatewaySupport {

    public static final String AP = "http://localhost:8888/";
//    public static final String AP = "http://localhost:8888/";

    @Test
    public void test() {
        getRestTemplate().getMessageConverters().add(new org.springframework.http.converter.json.MappingJackson2HttpMessageConverter());

        testDeleteCar();

//        testCreatePlaceOstrava();
//        testChangePlaceOwnerToPLace6();
//        testChangePlate();


//        testGetCar0();
//        testGetAllAll();
//        testRenamePlace1ToBrno();
//
//        testGetOwner0();
//        testGetAllOwners();
//        testPost();
//        testPut();
//        testGetAllOwners();
//
//        testDelete();
//        testGetAllOwners();


    }

    private void testDeleteCar() {
        String uri = AP;
        uri += "owners/0";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

        final UriComponentsBuilder uriComponentsBuilder2 = UriComponentsBuilder.fromUriString(AP + "cars/3");
        final String uriString2 = uriComponentsBuilder2.build().encode().toUriString();
        getRestTemplate().delete(uriString2);

        response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);


        final String s = UriComponentsBuilder.fromUriString(AP + "cars").build().encode().toUriString();
        response = getRestTemplate().getForObject(s, String.class);
        System.out.println(response);

    }

    private void testChangePlate() {
        String uri = AP;
        uri += "cars/2";
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();
        System.out.println(uriString);

        String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

        getRestTemplate().postForObject(uriString, new JSONWithNameAndPlate("BMW5", "plates/5"), String.class);

        response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);
    }

    private void testChangePlaceOwnerToPLace6() {
        String uri = AP;
        uri += "owners/0";
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();
        System.out.println(uriString);

        String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

        final List<String> strings = new ArrayList<String>();
        strings.add("cars/2");
        strings.add("cars/3");
        response = getRestTemplate().postForObject(uriString, new JSONForOwner("Al", "places/1", strings), String.class);
        System.out.println(response);


        response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

    }

    private void testCreatePlaceOstrava() {
        String uri = AP;
        uri += "places";
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

        getRestTemplate().put(uriString, new JSONWithName("Ostrava"));

        response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

    }


    private void testRenamePlace1ToBrno() {
        String uri = AP;
        uri += "places/1";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        System.out.println(uriString);

        getRestTemplate().postForObject(uriString, new JSONWithName("Brno"), String.class);

        String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

        getRestTemplate().postForObject(uriString, new JSONWithName("Praha"), String.class);

        response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);

    }

    private void testGetCar0() {
        String uri = AP;
        uri += "cars/0";
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();
        System.out.println(uriString);
        final String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);
    }


    private void testGetOwner0() {
        String uri = AP;
        uri += "owners/0";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);

        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        System.out.println(uriString);

        final String response = getRestTemplate().getForObject(uriString, String.class);

        System.out.println(response);
    }

    @Test
    public void testGetAllOwners() {
        String uri = AP;
        uri += "owners";
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();
        System.out.println(uriString);
        final String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);
    }

    @Test
    public void testGetAllAll() {
        printAllFor("owners");
        printAllFor("cars");
        printAllFor("plates");
        printAllFor("places");
    }


    private void printAllFor(String s) {
        String uri = AP + s;
        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();
        System.out.println(uriString);
        final String response = getRestTemplate().getForObject(uriString, String.class);
        System.out.println(response);
    }

    @Test
    public void testPost() {
        String uri = AP;
        uri += "owners/0";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        System.out.println(uriString);


        final JSONWithName ownerJSON = new JSONWithName("Allllesss");

        final String response = getRestTemplate().postForObject(uriString, ownerJSON, String.class);
        System.out.println(response);
    }

    @Test
    public void testDelete() {
        String uri = AP;
        uri += "owners/0";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        System.out.println(uriString);
        getRestTemplate().delete(uriString);

        System.out.println("HOTOVO");
    }

    @Test
    public void testPut() {
        String uri = AP;
        uri += "owners";

        final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(uri);
        final String uriString = uriComponentsBuilder.build().encode().toUriString();

        System.out.println(uriString);


//        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
//        map.add("name", "Zaza");
//        getRestTemplate().put(uriString, map);
        final JSONWithName ownerJSON = new JSONWithName("Zaza555");

        getRestTemplate().put(uriString, ownerJSON);

        System.out.println("HOTOVO");
    }

    @Override
    public RestTemplate getRestTemplate() {
        final RestTemplate restTemplate = super.getRestTemplate();
        return restTemplate;    //To change body of overridden methods use File | Settings | File Templates.
    }


    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class JSONWithName {

        @JsonProperty("name")
        private String name;

        public JSONWithName(String name) {
            this.name = name;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class JSONForOwner {

        @JsonProperty("name")
        private String name;

        @JsonProperty("place")
        private String place;

        @JsonProperty("cars")
        private List<String> cars;

        public JSONForOwner(String name, String place, List<String> cars) {
            this.name = name;
            this.place = place;
            this.cars = cars;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class JSONWithNameAndPlate {

        @JsonProperty("name")
        private String name;

        @JsonProperty("plate")
        private String plate;

        public JSONWithNameAndPlate(String name, String plate) {
            this.name = name;
            this.plate = plate;
        }
    }
}
